﻿using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SoulDoorEngine.Framework;
using SoulDoorEngine.Framework.Components;
using SoulDoorEngine.Framework.Services;
using SoulDoorEngine.Framework.Utilities;
using SoulDoorEngine.Components;
using SoulDoorEngine.Framework.Screens;
using SoulDoorEngine.Components.Cameras;
using SoulDoorEngine.Components.Smart2D.Basic;
using SoulDoorEngine.Components.Smart2D.Enums;
using SoulDoorEngine.Components.Smart2D.Events;
using SoulDoorEngine.Components.Smart2D.Info;
using SoulDoorEngine.Components.Smart2D.Objects;
using Microsoft.Xna.Framework.Input;
using System;

namespace SoulDoorEngine.Components.Smart2D.Objects
{
    public partial class GraphicObj : Component, I2DComponent
    {
        #region 原Obj属性
        private Vector _Position;
        private Vector _Velocity;
        private Vector _Acceleration;

        /// <summary>
        /// 位置
        /// </summary>
        public Vector Position
        {
            get { return _Position; }
            set { _Position = value; }
        }

        /// <summary>
        /// 速率
        /// </summary>
        public Vector Velocity
        {
            get { return _Velocity; }
            set { _Velocity = value; }
        }

        /// <summary>
        /// 加速度
        /// </summary>
        public Vector Acceleration
        {
            get { return _Acceleration; }
            set { _Acceleration = value; }
        }
        #endregion 原Obj属性


        #region 原GO属性
        #region
        private Texture2D _Resource;
        private Point _FrameSize;
        private Point _SheetSize;
        private Point _CurrentFrame;
        private event CollisionEventHandler _Collision = new CollisionEventHandler(OnCollision);
        private Color _Color = Color.White;
        private SpriteBatch _SpriteBatch;
        private float _Rotation = 0;
        private Vector2 _Origin = Vector2.Zero;
        private float _Scale = 1.0f;
        private SpriteEffects _Effects = SpriteEffects.None;
        private float _LayerDepth = 0;
        private int _FrameSpan = 1;
        private List<GraphicObj> _CollisionObjList = new List<GraphicObj>();
        private int _FrameSpanCount = 1;
        private Color[,] _ColorMatrix;
        private Matrix _TransformMatrix;
        private Color[] _ColorDate;
        private CollisionDetectionLevels _CollisionDetectionLevel = CollisionDetectionLevels.None;
        private Physic _Physics = null;
        private bool _IsPhysicsRun = false;
        private List<GraphicObj> _TouchObjList = new List<GraphicObj>();
        private MouseButtonDownDetectionLevels _MouseButtonDownDetectionLevel;
        private event MouseLeftButtonDownEventHandler _MouseLeftButtonDown = new MouseLeftButtonDownEventHandler(OnMouseButtonDown);
        private event MouseRightButtonDownEventHandler _MouseRightButtonDown = new MouseRightButtonDownEventHandler(OnMouseButtonDown);
        private MouseState _CurrentMouseState = new MouseState();
        private MouseState _LastMouseState = new MouseState();
        private object _Employer;
        private event LastFrameEventHandler _LastFrame = new LastFrameEventHandler(OnLastFrame);
        private int _CircleCount = 0;

        #endregion

        #region
        /// <summary>
        /// 循环数
        /// </summary>
        public int CircleCount
        {
            get { return _CircleCount; }
            set { _CircleCount = value; }
        }
        /// <summary>
        /// 最后帧事件
        /// </summary>
        public event LastFrameEventHandler LastFrame
        {
            add
            {
                lock (this._LastFrame)
                {
                    this._LastFrame += value;
                }
            }
            remove
            {
                lock (this._LastFrame)
                {
                    this._LastFrame -= value;
                }
            }
        }
        /// <summary>
        /// 雇主
        /// </summary>
        public object Employer
        {
            get { return _Employer; }
            set { _Employer = value; }
        }
        /// <summary>
        /// 上个鼠标状态
        /// </summary>
        private MouseState LastMouseState
        {
            get { return _LastMouseState; }
            set { _LastMouseState = value; }
        }
        /// <summary>
        /// 当前鼠标状态
        /// </summary>
        private MouseState CurrentMouseState
        {
            get { return _CurrentMouseState; }
            set { _CurrentMouseState = value; }
        }
        /// <summary>
        /// 鼠标右键事件
        /// </summary>
        public event MouseRightButtonDownEventHandler MouseRightButtonDown
        {
            add
            {
                lock (this._MouseRightButtonDown)
                {
                    this._MouseRightButtonDown += value;
                }
            }
            remove
            {
                lock (this._MouseRightButtonDown)
                {
                    this._MouseRightButtonDown -= value;
                }
            }
        }

        /// <summary>
        /// 鼠标左键事件
        /// </summary>
        public event MouseLeftButtonDownEventHandler MouseLeftButtonDown
        {
            add
            {
                lock (this._MouseLeftButtonDown)
                {
                    this._MouseLeftButtonDown += value;
                }
            }
            remove
            {
                lock (this._MouseLeftButtonDown)
                {
                    this._MouseLeftButtonDown -= value;
                }
            }
        }
        /// <summary>
        /// 鼠标按键按下检测等级
        /// </summary>
        public MouseButtonDownDetectionLevels MouseButtonDownDetectionLevel
        {
            get { return _MouseButtonDownDetectionLevel; }
            set { _MouseButtonDownDetectionLevel = value; }
        }
        /// <summary>
        /// 接触物体清单
        /// </summary>
        public List<GraphicObj> TouchObjList
        {
            get { return _TouchObjList; }
            set { _TouchObjList = value; }
        }
        /// <summary>
        /// 是否应用物理特性
        /// </summary>
        public bool IsPhysicsRun
        {
            get { return _IsPhysicsRun; }
            set { _IsPhysicsRun = value; }
        }
        /// <summary>
        /// 物理特性
        /// </summary>
        public Physic Physics
        {
            get { return _Physics; }
            set { _Physics = value; }
        }
        /// <summary>
        /// 当前帧在屏幕上所在矩形
        /// </summary>
        public Rectangle Rectangle
        {
            get { return new Rectangle((int)(this.Position.X - this.Origin.X), (int)(this.Position.Y - this.Origin.Y), (int)this.FrameSize.X, (int)this.FrameSize.Y); }
            set { }
        }
        /// <summary>
        /// 碰撞检测等级，开销从低到高，准确率从高到低依次为：无碰撞检测、矩形碰撞检测、像素碰撞检测、旋转物的碰撞检测
        /// </summary>
        public CollisionDetectionLevels CollisionDetectionLevel
        {
            get { return _CollisionDetectionLevel; }
            set { _CollisionDetectionLevel = value; }
        }
        /// <summary>
        /// 色彩数据
        /// </summary>
        public Color[] ColorDate
        {
            get { return _ColorDate; }
            private set { _ColorDate = value; }
        }
        /// <summary>
        /// 转化矩阵
        /// </summary>
        public Matrix TransformMatrix
        {
            get { return _TransformMatrix; }
            private set { _TransformMatrix = value; }
        }
        /// <summary>
        /// 色彩矩阵
        /// </summary>
        public Color[,] ColorMatrix
        {
            get { return _ColorMatrix; }
            private set { _ColorMatrix = value; }
        }
        /// <summary>
        /// 帧间隔计数器
        /// </summary>
        private int FrameSpanCount
        {
            get { return _FrameSpanCount; }
            set { _FrameSpanCount = value; }
        }
        /// <summary>
        /// 碰撞检测清单
        /// </summary>
        public List<GraphicObj> CollisionObjList
        {
            get { return _CollisionObjList; }
            set { _CollisionObjList = value; }
        }

        /// <summary>
        /// 显示尺寸
        /// </summary>
        public Vector Size
        {
            get { return new Vector(FrameSize.X * Scale, FrameSize.Y * Scale); }
        }
        /// <summary>
        /// 中心坐标
        /// </summary>
        public Vector Centre
        {
            get { return new Vector(Position.X + Size.X / 2.0f - Origin.X, Position.Y + Size.Y / 2.0f - Origin.Y); }
        }
        /// <summary>
        /// 帧间隔
        /// </summary>
        public int FrameSpan
        {
            get { return _FrameSpan; }
            set { _FrameSpan = value; }
        }
        /// <summary>
        /// 渲染层深
        /// </summary>
        public float LayerDepth
        {
            get { return _LayerDepth; }
            set { _LayerDepth = value; }
        }

        /// <summary>
        /// 渲染特效，如翻转
        /// </summary>
        public SpriteEffects Effects
        {
            get { return _Effects; }
            set { _Effects = value; }
        }

        /// <summary>
        /// 渲染倍数
        /// </summary>
        public float Scale
        {
            get { return _Scale; }
            set
            {
                _Scale = value;
            }
        }

        /// <summary>
        /// 旋转原点
        /// </summary>
        public Vector2 Origin
        {
            get { return _Origin; }
            set { _Origin = value; }
        }

        /// <summary>
        /// 旋转角度
        /// </summary>
        public float Rotation
        {
            get { return _Rotation; }
            set { _Rotation = value; }
        }

        /// <summary>
        /// 精灵
        /// </summary>
        public SpriteBatch SpriteBatch
        {
            get { return _SpriteBatch; }
            set { _SpriteBatch = value; }
        }

        /// <summary>
        /// 渲染用色彩
        /// </summary>
        public Color Color
        {
            get { return _Color; }
            set { _Color = value; }
        }

        /// <summary>
        /// 碰撞事件
        /// </summary>
        public event CollisionEventHandler Collision
        {
            add
            {
                lock (this._Collision)
                {
                    this._Collision += value;
                }
            }
            remove
            {
                lock (this._Collision)
                {
                    this._Collision -= value;
                }
            }
        }

        /// <summary>
        /// 纹理资源
        /// </summary>
        public Texture2D Resource
        {
            get { return _Resource; }
            set
            {
                _Resource = value;
                this.ColorDate = new Color[Resource.Width * Resource.Height];
                Resource.GetData(ColorDate);
            }
        }

        /// <summary>
        /// 帧大小
        /// </summary>
        public Point FrameSize
        {
            get { return _FrameSize; }
            set
            {
                _FrameSize = value;
                this.ColorMatrix = new Color[this.FrameSize.Y, this.FrameSize.X];
                this.ColorMatrixUpdateOnce();
            }
        }

        /// <summary>
        /// 纹理资源结构
        /// </summary>
        public Point SheetSize
        {
            get { return _SheetSize; }
            set { _SheetSize = value; }
        }

        /// <summary>
        /// 当前帧
        /// </summary>
        public Point CurrentFrame
        {
            get { return _CurrentFrame; }
            set
            {
                _CurrentFrame = value;
                this.ColorMatrixUpdate();
            }
        }
        #endregion

        /// <summary>
        /// 构造函数
        /// </summary>
        public GraphicObj()
            : base()
        {
            GraphicObj.Add(this);
        }

        public GraphicObj(Screen parent)
            : base(parent)
        {
            GraphicObj.Add(this);
        }

        /// <summary>
        /// 构造函数 置于LoadContent()下
        /// </summary>
        /// <param name="obj">基类实例</param>
        /// <param name="contentName">纹理资源名</param>
        /// <param name="game">Game实例</param>
        /// <param name="frameSize">帧大小</param>
        /// <param name="sheetSize">纹理资源结构</param>
        /// <param name="currentFrame">当前帧</param>
        /// <param name="frameSpan">帧间隔</param>
        public GraphicObj(Vector position, Vector velocity, Vector acceleration,
            string contentName, Game game, Point frameSize, Point sheetSize, Point currentFrame,
            int frameSpan, object employer)
            : base()
        {
            this.Position = position;
            this.Velocity = velocity;
            this.Acceleration = acceleration;
            this.Resource = game.Content.Load<Texture2D>(contentName);
            this.SheetSize = sheetSize;
            this.FrameSize = frameSize;
            this.CurrentFrame = currentFrame;
            this.FrameSpan = frameSpan;
            this.FrameSpanCount = this.FrameSpan;
            this.Employer = employer;
            GraphicObj.Add(this);
        }

        /// <summary>
        /// 构造函数 置于LoadContent()下
        /// </summary>
        /// <param name="obj">基类实例</param>
        /// <param name="contentName">纹理资源名</param>
        /// <param name="game">Game实例</param>
        /// <param name="frameSize">帧大小</param>
        /// <param name="sheetSize">纹理资源结构</param>
        /// <param name="currentFrame">当前帧</param>
        /// <param name="frameSpan">帧间隔</param>
        /// <param name="collisionDetectionLevel">碰撞检测等级</param>
        /// <param name="mouseButtonDownDetectionLevel">鼠标按键检测等级</param>
        public GraphicObj(Vector position, Vector velocity, Vector acceleration,
            string contentName, Game game, Point frameSize, Point sheetSize, Point currentFrame,
            int frameSpan, object employer,
            CollisionDetectionLevels collisionDetectionLevel,
            MouseButtonDownDetectionLevels mouseButtonDownDetectionLevel)
            : base()
        {
            this.CollisionDetectionLevel = collisionDetectionLevel;
            this.MouseButtonDownDetectionLevel = mouseButtonDownDetectionLevel;
            this.Position = position;
            this.Velocity = velocity;
            this.Acceleration = acceleration;
            this.Resource = game.Content.Load<Texture2D>(contentName);
            //***************************************************************************//
            //***************************************************************************//
            //***************************************************************************//
            //2012.03.03修复BUG：FrameSize必须在SheetSize后初始化，否则将可能使用空的SheetSize*//
            //***************************************************************************//
            //***************************************************************************//
            //***************************************************************************//
            this.SheetSize = sheetSize;
            this.FrameSize = frameSize;
            this.CurrentFrame = currentFrame;
            this.FrameSpan = frameSpan;
            this.FrameSpanCount = this.FrameSpan;
            this.Employer = employer;
            GraphicObj.Add(this);
        }
        /// <summary>
        /// 构造函数 置于LoadContent()下
        /// </summary>
        /// <param name="obj">基类实例</param>
        /// <param name="contentName">纹理资源名</param>
        /// <param name="game">Game实例</param>
        /// <param name="frameSize">帧大小</param>
        /// <param name="sheetSize">纹理资源结构</param>
        /// <param name="currentFrame">当前帧</param>
        /// <param name="frameSpan">帧间隔</param>
        /// <param name="collisionDetectionLevel">碰撞检测等级</param>
        /// <param name="mouseButtonDownDetectionLevel">鼠标按键检测等级</param>
        /// <param name="isPhysicsRun">是否应用物理特性</param>
        public GraphicObj(Vector position, Vector velocity, Vector acceleration,
            string contentName, Game game, Point frameSize, Point sheetSize, Point currentFrame,
            int frameSpan, object employer,
            CollisionDetectionLevels collisionDetectionLevel,
            MouseButtonDownDetectionLevels mouseButtonDownDetectionLevel, bool isPhysicsRun)
            : base()
        {
            this.CollisionDetectionLevel = collisionDetectionLevel;
            this.MouseButtonDownDetectionLevel = mouseButtonDownDetectionLevel;
            this.Position = position;
            this.Velocity = velocity;
            this.Acceleration = acceleration;
            this.Resource = game.Content.Load<Texture2D>(contentName);
            this.SheetSize = sheetSize;
            this.FrameSize = frameSize;
            this.CurrentFrame = currentFrame;
            this.FrameSpan = frameSpan;
            this.FrameSpanCount = this.FrameSpan;
            this.Employer = employer;
            this.IsPhysicsRun = isPhysicsRun;
            if (IsPhysicsRun)
            {
                this.Physics = new Physic(this);
            }
            GraphicObj.Add(this);
        }

        #region
        /// <summary>
        /// 构造函数 置于LoadContent()下
        /// </summary>
        /// <param name="positionX">位置向量水平方向分量</param>
        /// <param name="positionY">位置向量竖直方向分量</param>
        /// <param name="velocityX">速度向量水平方向分量</param>
        /// <param name="velocityY">速度向量竖直方向分量</param>
        /// <param name="accelerationX">加速度向量水平方向分量</param>
        /// <param name="accelerationY">加速度向量竖直方向分量</param>
        /// <param name="contentName">纹理所在资源名</param>
        /// <param name="game">Game实例</param>
        /// <param name="frameSizeX">帧宽</param>
        /// <param name="frameSizeY">帧高</param>
        /// <param name="sheetSizeX">帧资源中水平方向帧数量</param>
        /// <param name="sheetSizeY">帧资源中竖直方向帧数量</param>
        /// <param name="currentFrameX">当前帧水平方向序号，从0开始</param>
        /// <param name="currentFrameY">当前帧竖直方向序号，从0开始</param>
        /// <param name="frameSpan">帧间隔</param>
        public GraphicObj(
            float positionX, float positionY,
            float velocityX, float velocityY,
            float accelerationX, float accelerationY,
            string contentName, Game game,
            int frameSizeX, int frameSizeY,
            int sheetSizeX, int sheetSizeY,
            int currentFrameX, int currentFrameY,
            int frameSpan,
            object employer)
            : base()
        {
            this.Position = new Vector(positionX, positionY);
            this.Velocity = new Vector(velocityX, velocityY);
            this.Acceleration = new Vector(accelerationX, accelerationY);
            this.Resource = game.Content.Load<Texture2D>(contentName);
            this.SheetSize = new Point(sheetSizeX, sheetSizeY);
            this.FrameSize = new Point(frameSizeX, frameSizeY);
            this.CurrentFrame = new Point(currentFrameX, currentFrameY);
            this.FrameSpan = frameSpan;
            this.FrameSpanCount = this.FrameSpan;
            this.Employer = employer;
            GraphicObj.Add(this);
        }
        #endregion

        #region
        /// <summary>
        /// 构造函数 置于LoadContent()下
        /// </summary>
        /// <param name="positionX">位置向量水平方向分量</param>
        /// <param name="positionY">位置向量竖直方向分量</param>
        /// <param name="velocityX">速度向量水平方向分量</param>
        /// <param name="velocityY">速度向量竖直方向分量</param>
        /// <param name="accelerationX">加速度向量水平方向分量</param>
        /// <param name="accelerationY">加速度向量竖直方向分量</param>
        /// <param name="contentName">纹理所在资源名</param>
        /// <param name="game">Game实例</param>
        /// <param name="frameSizeX">帧宽</param>
        /// <param name="frameSizeY">帧高</param>
        /// <param name="sheetSizeX">帧资源中水平方向帧数量</param>
        /// <param name="sheetSizeY">帧资源中竖直方向帧数量</param>
        /// <param name="currentFrameX">当前帧水平方向序号，从0开始</param>
        /// <param name="currentFrameY">当前帧竖直方向序号，从0开始</param>
        /// <param name="frameSpan">帧间隔</param>
        /// <param name="collisionDetectionLevel">碰撞检测等级</param>
        /// <param name="mouseButtonDownDetectionLevel">鼠标按键检测等级</param>
        public GraphicObj(
            float positionX, float positionY,
            float velocityX, float velocityY,
            float accelerationX, float accelerationY,
            string contentName, Game game,
            int frameSizeX, int frameSizeY,
            int sheetSizeX, int sheetSizeY,
            int currentFrameX, int currentFrameY,
            int frameSpan,
            object employer,
            CollisionDetectionLevels collisionDetectionLevel,
            MouseButtonDownDetectionLevels mouseButtonDownDetectionLevel)
            : base()
        {
            this.CollisionDetectionLevel = collisionDetectionLevel;
            this.MouseButtonDownDetectionLevel = mouseButtonDownDetectionLevel;
            this.Position = new Vector(positionX, positionY);
            this.Velocity = new Vector(velocityX, velocityY);
            this.Acceleration = new Vector(accelerationX, accelerationY);
            this.Resource = game.Content.Load<Texture2D>(contentName);
            this.SheetSize = new Point(sheetSizeX, sheetSizeY);
            this.FrameSize = new Point(frameSizeX, frameSizeY);
            this.CurrentFrame = new Point(currentFrameX, currentFrameY);
            this.FrameSpan = frameSpan;
            this.FrameSpanCount = this.FrameSpan;
            this.Employer = employer;
            GraphicObj.Add(this);
        }
        #endregion

        #region
        /// <summary>
        /// 构造函数 置于LoadContent()下
        /// </summary>
        /// <param name="positionX">位置向量水平方向分量</param>
        /// <param name="positionY">位置向量竖直方向分量</param>
        /// <param name="velocityX">速度向量水平方向分量</param>
        /// <param name="velocityY">速度向量竖直方向分量</param>
        /// <param name="accelerationX">加速度向量水平方向分量</param>
        /// <param name="accelerationY">加速度向量竖直方向分量</param>
        /// <param name="contentName">纹理所在资源名</param>
        /// <param name="game">Game实例</param>
        /// <param name="frameSizeX">帧宽</param>
        /// <param name="frameSizeY">帧高</param>
        /// <param name="sheetSizeX">帧资源中水平方向帧数量</param>
        /// <param name="sheetSizeY">帧资源中竖直方向帧数量</param>
        /// <param name="currentFrameX">当前帧水平方向序号，从0开始</param>
        /// <param name="currentFrameY">当前帧竖直方向序号，从0开始</param>
        /// <param name="frameSpan">帧间隔</param>
        /// <param name="collisionDetectionLevel">碰撞检测等级</param>
        /// <param name="mouseButtonDownDetectionLevel">鼠标按键检测等级</param>
        /// <param name="isPhysicsRun">是否应用物理特性</param>
        public GraphicObj(
            float positionX, float positionY,
            float velocityX, float velocityY,
            float accelerationX, float accelerationY,
            string contentName, Game game,
            int frameSizeX, int frameSizeY,
            int sheetSizeX, int sheetSizeY,
            int currentFrameX, int currentFrameY,
            int frameSpan,
            object employer,
            CollisionDetectionLevels collisionDetectionLevel,
            MouseButtonDownDetectionLevels mouseButtonDownDetectionLevel,
            bool isPhysicsRun)
            : base()
        {
            this.CollisionDetectionLevel = collisionDetectionLevel;
            this.MouseButtonDownDetectionLevel = mouseButtonDownDetectionLevel;
            this.Position = new Vector(positionX, positionY);
            this.Velocity = new Vector(velocityX, velocityY);
            this.Acceleration = new Vector(accelerationX, accelerationY);
            this.Resource = game.Content.Load<Texture2D>(contentName);
            this.SheetSize = new Point(sheetSizeX, sheetSizeY);
            this.FrameSize = new Point(frameSizeX, frameSizeY);
            this.CurrentFrame = new Point(currentFrameX, currentFrameY);
            this.FrameSpan = frameSpan;
            this.FrameSpanCount = this.FrameSpan;
            this.Employer = employer;
            this.IsPhysicsRun = isPhysicsRun;
            if (IsPhysicsRun)
            {
                this.Physics = new Physic(this);
            }
            GraphicObj.Add(this);
        }
        #endregion

        #region Parent版本构造函数集合
        /// <summary>
        /// 构造函数 置于LoadContent()下
        /// </summary>
        /// <param name="obj">基类实例</param>
        /// <param name="contentName">纹理资源名</param>
        /// <param name="game">Game实例</param>
        /// <param name="frameSize">帧大小</param>
        /// <param name="sheetSize">纹理资源结构</param>
        /// <param name="currentFrame">当前帧</param>
        /// <param name="frameSpan">帧间隔</param>
        public GraphicObj(Vector position, Vector velocity, Vector acceleration,
            string contentName, Game game, Point frameSize, Point sheetSize, Point currentFrame,
            int frameSpan, object employer,
            Screen parent)
            : base(parent)
        {
            this.Position = position;
            this.Velocity = velocity;
            this.Acceleration = acceleration;
            this.Resource = game.Content.Load<Texture2D>(contentName);
            this.SheetSize = sheetSize;
            this.FrameSize = frameSize;
            this.CurrentFrame = currentFrame;
            this.FrameSpan = frameSpan;
            this.FrameSpanCount = this.FrameSpan;
            this.Employer = employer;
            GraphicObj.Add(this);
        }

        /// <summary>
        /// 构造函数 置于LoadContent()下
        /// </summary>
        /// <param name="obj">基类实例</param>
        /// <param name="contentName">纹理资源名</param>
        /// <param name="game">Game实例</param>
        /// <param name="frameSize">帧大小</param>
        /// <param name="sheetSize">纹理资源结构</param>
        /// <param name="currentFrame">当前帧</param>
        /// <param name="frameSpan">帧间隔</param>
        /// <param name="collisionDetectionLevel">碰撞检测等级</param>
        /// <param name="mouseButtonDownDetectionLevel">鼠标按键检测等级</param>
        public GraphicObj(Vector position, Vector velocity, Vector acceleration,
            string contentName, Game game, Point frameSize, Point sheetSize, Point currentFrame,
            int frameSpan, object employer,
            CollisionDetectionLevels collisionDetectionLevel,
            MouseButtonDownDetectionLevels mouseButtonDownDetectionLevel,
            Screen parent)
            : base(parent)
        {
            this.CollisionDetectionLevel = collisionDetectionLevel;
            this.MouseButtonDownDetectionLevel = mouseButtonDownDetectionLevel;
            this.Position = position;
            this.Velocity = velocity;
            this.Acceleration = acceleration;
            this.Resource = game.Content.Load<Texture2D>(contentName);
            this.SheetSize = sheetSize;
            this.FrameSize = frameSize;
            this.CurrentFrame = currentFrame;
            this.FrameSpan = frameSpan;
            this.FrameSpanCount = this.FrameSpan;
            this.Employer = employer;
            GraphicObj.Add(this);
        }
        /// <summary>
        /// 构造函数 置于LoadContent()下
        /// </summary>
        /// <param name="obj">基类实例</param>
        /// <param name="contentName">纹理资源名</param>
        /// <param name="game">Game实例</param>
        /// <param name="frameSize">帧大小</param>
        /// <param name="sheetSize">纹理资源结构</param>
        /// <param name="currentFrame">当前帧</param>
        /// <param name="frameSpan">帧间隔</param>
        /// <param name="collisionDetectionLevel">碰撞检测等级</param>
        /// <param name="mouseButtonDownDetectionLevel">鼠标按键检测等级</param>
        /// <param name="isPhysicsRun">是否应用物理特性</param>
        public GraphicObj(Vector position, Vector velocity, Vector acceleration,
            string contentName, Game game, Point frameSize, Point sheetSize, Point currentFrame,
            int frameSpan, object employer,
            CollisionDetectionLevels collisionDetectionLevel,
            MouseButtonDownDetectionLevels mouseButtonDownDetectionLevel, bool isPhysicsRun,
            Screen parent)
            : base(parent)
        {
            this.CollisionDetectionLevel = collisionDetectionLevel;
            this.MouseButtonDownDetectionLevel = mouseButtonDownDetectionLevel;
            this.Position = position;
            this.Velocity = velocity;
            this.Acceleration = acceleration;
            this.Resource = game.Content.Load<Texture2D>(contentName);
            this.SheetSize = sheetSize;
            this.FrameSize = frameSize;
            this.CurrentFrame = currentFrame;
            this.FrameSpan = frameSpan;
            this.FrameSpanCount = this.FrameSpan;
            this.Employer = employer;
            this.IsPhysicsRun = isPhysicsRun;
            if (IsPhysicsRun)
            {
                this.Physics = new Physic(this);
            }
            GraphicObj.Add(this);
        }

        #region
        /// <summary>
        /// 构造函数 置于LoadContent()下
        /// </summary>
        /// <param name="positionX">位置向量水平方向分量</param>
        /// <param name="positionY">位置向量竖直方向分量</param>
        /// <param name="velocityX">速度向量水平方向分量</param>
        /// <param name="velocityY">速度向量竖直方向分量</param>
        /// <param name="accelerationX">加速度向量水平方向分量</param>
        /// <param name="accelerationY">加速度向量竖直方向分量</param>
        /// <param name="contentName">纹理所在资源名</param>
        /// <param name="game">Game实例</param>
        /// <param name="frameSizeX">帧宽</param>
        /// <param name="frameSizeY">帧高</param>
        /// <param name="sheetSizeX">帧资源中水平方向帧数量</param>
        /// <param name="sheetSizeY">帧资源中竖直方向帧数量</param>
        /// <param name="currentFrameX">当前帧水平方向序号，从0开始</param>
        /// <param name="currentFrameY">当前帧竖直方向序号，从0开始</param>
        /// <param name="frameSpan">帧间隔</param>
        public GraphicObj(
            float positionX, float positionY,
            float velocityX, float velocityY,
            float accelerationX, float accelerationY,
            string contentName, Game game,
            int frameSizeX, int frameSizeY,
            int sheetSizeX, int sheetSizeY,
            int currentFrameX, int currentFrameY,
            int frameSpan,
            object employer,
            Screen parent)
            : base(parent)
        {
            this.Position = new Vector(positionX, positionY);
            this.Velocity = new Vector(velocityX, velocityY);
            this.Acceleration = new Vector(accelerationX, accelerationY);
            this.Resource = game.Content.Load<Texture2D>(contentName);
            this.SheetSize = new Point(sheetSizeX, sheetSizeY);
            this.FrameSize = new Point(frameSizeX, frameSizeY);
            this.CurrentFrame = new Point(currentFrameX, currentFrameY);
            this.FrameSpan = frameSpan;
            this.FrameSpanCount = this.FrameSpan;
            this.Employer = employer;
            GraphicObj.Add(this);
        }
        #endregion

        #region
        /// <summary>
        /// 构造函数 置于LoadContent()下
        /// </summary>
        /// <param name="positionX">位置向量水平方向分量</param>
        /// <param name="positionY">位置向量竖直方向分量</param>
        /// <param name="velocityX">速度向量水平方向分量</param>
        /// <param name="velocityY">速度向量竖直方向分量</param>
        /// <param name="accelerationX">加速度向量水平方向分量</param>
        /// <param name="accelerationY">加速度向量竖直方向分量</param>
        /// <param name="contentName">纹理所在资源名</param>
        /// <param name="game">Game实例</param>
        /// <param name="frameSizeX">帧宽</param>
        /// <param name="frameSizeY">帧高</param>
        /// <param name="sheetSizeX">帧资源中水平方向帧数量</param>
        /// <param name="sheetSizeY">帧资源中竖直方向帧数量</param>
        /// <param name="currentFrameX">当前帧水平方向序号，从0开始</param>
        /// <param name="currentFrameY">当前帧竖直方向序号，从0开始</param>
        /// <param name="frameSpan">帧间隔</param>
        /// <param name="collisionDetectionLevel">碰撞检测等级</param>
        /// <param name="mouseButtonDownDetectionLevel">鼠标按键检测等级</param>
        public GraphicObj(
            float positionX, float positionY,
            float velocityX, float velocityY,
            float accelerationX, float accelerationY,
            string contentName, Game game,
            int frameSizeX, int frameSizeY,
            int sheetSizeX, int sheetSizeY,
            int currentFrameX, int currentFrameY,
            int frameSpan,
            object employer,
            CollisionDetectionLevels collisionDetectionLevel,
            MouseButtonDownDetectionLevels mouseButtonDownDetectionLevel,
            Screen parent)
            : base(parent)
        {
            this.CollisionDetectionLevel = collisionDetectionLevel;
            this.MouseButtonDownDetectionLevel = mouseButtonDownDetectionLevel;
            this.Position = new Vector(positionX, positionY);
            this.Velocity = new Vector(velocityX, velocityY);
            this.Acceleration = new Vector(accelerationX, accelerationY);
            this.Resource = game.Content.Load<Texture2D>(contentName);
            this.SheetSize = new Point(sheetSizeX, sheetSizeY);
            this.FrameSize = new Point(frameSizeX, frameSizeY);
            this.CurrentFrame = new Point(currentFrameX, currentFrameY);
            this.FrameSpan = frameSpan;
            this.FrameSpanCount = this.FrameSpan;
            this.Employer = employer;
            GraphicObj.Add(this);
        }
        #endregion

        #region
        /// <summary>
        /// 构造函数 置于LoadContent()下
        /// </summary>
        /// <param name="positionX">位置向量水平方向分量</param>
        /// <param name="positionY">位置向量竖直方向分量</param>
        /// <param name="velocityX">速度向量水平方向分量</param>
        /// <param name="velocityY">速度向量竖直方向分量</param>
        /// <param name="accelerationX">加速度向量水平方向分量</param>
        /// <param name="accelerationY">加速度向量竖直方向分量</param>
        /// <param name="contentName">纹理所在资源名</param>
        /// <param name="game">Game实例</param>
        /// <param name="frameSizeX">帧宽</param>
        /// <param name="frameSizeY">帧高</param>
        /// <param name="sheetSizeX">帧资源中水平方向帧数量</param>
        /// <param name="sheetSizeY">帧资源中竖直方向帧数量</param>
        /// <param name="currentFrameX">当前帧水平方向序号，从0开始</param>
        /// <param name="currentFrameY">当前帧竖直方向序号，从0开始</param>
        /// <param name="frameSpan">帧间隔</param>
        /// <param name="collisionDetectionLevel">碰撞检测等级</param>
        /// <param name="mouseButtonDownDetectionLevel">鼠标按键检测等级</param>
        /// <param name="isPhysicsRun">是否应用物理特性</param>
        public GraphicObj(
            float positionX, float positionY,
            float velocityX, float velocityY,
            float accelerationX, float accelerationY,
            string contentName, Game game,
            int frameSizeX, int frameSizeY,
            int sheetSizeX, int sheetSizeY,
            int currentFrameX, int currentFrameY,
            int frameSpan,
            object employer,
            CollisionDetectionLevels collisionDetectionLevel,
            MouseButtonDownDetectionLevels mouseButtonDownDetectionLevel,
            bool isPhysicsRun,
            Screen parent)
            : base(parent)
        {
            this.CollisionDetectionLevel = collisionDetectionLevel;
            this.MouseButtonDownDetectionLevel = mouseButtonDownDetectionLevel;
            this.Position = new Vector(positionX, positionY);
            this.Velocity = new Vector(velocityX, velocityY);
            this.Acceleration = new Vector(accelerationX, accelerationY);
            this.Resource = game.Content.Load<Texture2D>(contentName);
            this.SheetSize = new Point(sheetSizeX, sheetSizeY);
            this.FrameSize = new Point(frameSizeX, frameSizeY);
            this.CurrentFrame = new Point(currentFrameX, currentFrameY);
            this.FrameSpan = frameSpan;
            this.FrameSpanCount = this.FrameSpan;
            this.Employer = employer;
            this.IsPhysicsRun = isPhysicsRun;
            if (IsPhysicsRun)
            {
                this.Physics = new Physic(this);
            }
            GraphicObj.Add(this);
        }
        #endregion
        #endregion Parent版本构造函数集合

        /// <summary>
        /// 更新当前帧，置于Update()下
        /// </summary>
        public override void Update()
        {
            this.FrameUpdate();
            this.PositionUpdate();
            this.MouseButtonDownDetection();
            this.TransformMatrixUpdate();
            //this.CollisionDetectionOld(this.CollisionObjList);
            this.CollisionDetection();
            this.PhysicsUpdate();
            GraphicObj.Plus();
            if (GraphicObj.TimesUpdate == GraphicObj.CountGO)
            {
                GraphicObj.AfterAllUpdate();
            }
        }

        internal void PhysicsUpdate()
        {
            if (this.IsPhysicsRun)
            {
                this.Physics.Update();
            }
        }

        internal void FrameUpdate()
        {
            --this.FrameSpanCount;
            if (this.FrameSpanCount <= 0)
            {
                this.FrameSpanCount = this.FrameSpan;
                if (CurrentFrame.X + 1 < SheetSize.X)
                {
                    this.SetCurrentFrameX(this.CurrentFrame.X + 1);
                }
                else
                {
                    this.CircleCount++;
                    this.RaiseLastFrameEvent(this.FrameSize.X + 1, this.CircleCount);
                    this.SetCurrentFrameX(0);
                }
            }
        }

        internal void PositionUpdate()
        {
            this.Velocity += this.Acceleration / (float)this.FrameSpan;
            this.Position += this.Velocity;
        }

        internal void PositionUpdate(Vector centre)
        {
            this.Position.SetX(GetPositionFromCentre(centre).X);
            this.Position.SetY(GetPositionFromCentre(centre).Y);
        }

        internal void TransformMatrixUpdate()
        {
            if (this.CollisionDetectionLevel != CollisionDetectionLevels.TransformedCollision)
            {
                return;
            }
            this.TransformMatrix = Matrix.CreateTranslation(new Vector3(-Origin, 0.0f)) *
                            Matrix.CreateScale(Scale) *
                            Matrix.CreateRotationZ(Rotation) *
                            Matrix.CreateTranslation(new Vector3(new Vector2(Position.X, Position.Y), 0.0f));
        }

        internal void ColorMatrixUpdate()
        {
            if (this.SheetSize.Y <= 1 && this.SheetSize.X <= 1)
            {
                return;
            }
            if (
                (this.CollisionDetectionLevel == CollisionDetectionLevels.None || this.CollisionDetectionLevel == CollisionDetectionLevels.RectangleCollision)
                && (this.MouseButtonDownDetectionLevel == MouseButtonDownDetectionLevels.None || this.MouseButtonDownDetectionLevel == MouseButtonDownDetectionLevels.RectangleCollision))
            {
                return;
            }
            if (Resource == null || FrameSize == null || CurrentFrame == null || ColorDate == null || FrameSize.X == 0 || FrameSize.Y == 0)
            {
                return;
            }
            for (int i = 0; i < this.FrameSize.Y; ++i)
            {
                for (int j = 0; j < this.FrameSize.X; ++j)
                {
                    ColorMatrix[i, j] = ColorDate[(CurrentFrame.Y * FrameSize.Y + i) * FrameSize.X * SheetSize.X + CurrentFrame.X * FrameSize.X + j];
                }
            }
        }

        internal void ColorMatrixUpdateOnce()
        {
            if (
                (this.CollisionDetectionLevel == CollisionDetectionLevels.None || this.CollisionDetectionLevel == CollisionDetectionLevels.RectangleCollision)
                && (this.MouseButtonDownDetectionLevel == MouseButtonDownDetectionLevels.None || this.MouseButtonDownDetectionLevel == MouseButtonDownDetectionLevels.RectangleCollision))
            {
                return;
            }
            if (Resource == null || FrameSize == null || CurrentFrame == null || ColorDate == null || FrameSize.X == 0 || FrameSize.Y == 0)
            {
                return;
            }
            for (int i = 0; i < this.FrameSize.Y; ++i)
            {
                for (int j = 0; j < this.FrameSize.X; ++j)
                {
                    ColorMatrix[i, j] = ColorDate[(CurrentFrame.Y * FrameSize.Y + i) * FrameSize.X * SheetSize.X + CurrentFrame.X * FrameSize.X + j];
                }
            }
        }

        internal bool TransformIntersectPixels_2(GraphicObj go)
        {
            // Calculate a matrix which transforms from A's local space into
            // world space and then into B's local space
            Matrix transformAToB = this.TransformMatrix * Matrix.Invert(go.TransformMatrix);

            // When a point moves in A's local space, it moves in B's local space with a
            // fixed direction and distance proportional to the movement in A.
            // This algorithm steps through A one pixel at a time along A's X and Y axes
            // Calculate the analogous steps in B:
            Vector2 stepX = Vector2.TransformNormal(Vector2.UnitX, transformAToB);
            Vector2 stepY = Vector2.TransformNormal(Vector2.UnitY, transformAToB);

            // Calculate the top left corner of A in B's local space
            // This variable will be reused to keep track of the start of each row
            Vector2 yPosInB = Vector2.Transform(Vector2.Zero, transformAToB);

            // For each row of pixels in A
            for (int yA = 0; yA < this.FrameSize.Y; yA++)
            {
                // Start at the beginning of the row
                Vector2 posInB = yPosInB;

                // For each pixel in this row
                for (int xA = 0; xA < this.FrameSize.X; xA++)
                {
                    // Round to the nearest pixel
                    int xB = (int)System.Math.Round(posInB.X);
                    int yB = (int)System.Math.Round(posInB.Y);

                    // If the pixel lies within the bounds of B
                    if (0 <= xB && xB < go.FrameSize.X &&
                        0 <= yB && yB < go.FrameSize.Y)
                    {
                        // Get the colors of the overlapping pixels
                        Color colorA = this.ColorMatrix[yA, xA];
                        Color colorB = go.ColorMatrix[yB, xB];

                        // If both pixels are not completely transparent,
                        if (colorA.A != 0 && colorB.A != 0)
                        {
                            // then an intersection has been found
                            return true;
                        }
                    }

                    // Move to the next pixel in the row
                    posInB += stepX;
                }

                // Move to the next row
                yPosInB += stepY;
            }

            // No intersection found
            return false;
        }

        internal bool TransformIntersectPixels(GraphicObj go, ref Vector position)
        {
            // Calculate a matrix which transforms from A's local space into
            // world space and then into B's local space
            Matrix transformAToB = this.TransformMatrix * Matrix.Invert(go.TransformMatrix);

            // For each row of pixels in A
            for (int yA = 0; yA < this.FrameSize.Y; yA++)
            {
                // For each pixel in this row
                for (int xA = 0; xA < this.FrameSize.X; xA++)
                {
                    // Calculate this pixel's location in B
                    Vector2 positionInB =
                        Vector2.Transform(new Vector2(xA, yA), transformAToB);

                    // Round to the nearest pixel
                    int xB = (int)System.Math.Round(positionInB.X);
                    int yB = (int)System.Math.Round(positionInB.Y);

                    // If the pixel lies within the bounds of B
                    if (0 <= xB && xB < go.FrameSize.X &&
                        0 <= yB && yB < go.FrameSize.Y)
                    {
                        // Get the colors of the overlapping pixels
                        Color colorA = this.ColorMatrix[yA, xA];
                        Color colorB = go.ColorMatrix[yB, xB];

                        // If both pixels are not completely transparent,
                        if (colorA.A != 0 && colorB.A != 0)
                        {
                            // then an intersection has been found
                            position = new Vector(Vector2.Transform(new Vector2(xA, yA), this.TransformMatrix).X, Vector2.Transform(new Vector2(xA, yA), this.TransformMatrix).Y);
                            return true;
                        }
                    }
                }
            }

            // No intersection found
            return false;
        }

        internal bool IntersectPixels(GraphicObj go, ref Vector position)
        {
            Rectangle rectangleA = this.Rectangle;
            Rectangle rectangleB = go.Rectangle;
            // Find the bounds of the rectangle intersection
            int top = System.Math.Max(rectangleA.Top, rectangleB.Top);
            int bottom = System.Math.Min(rectangleA.Bottom, rectangleB.Bottom);
            int left = System.Math.Max(rectangleA.Left, rectangleB.Left);
            int right = System.Math.Min(rectangleA.Right, rectangleB.Right);

            // Check every point within the intersection bounds
            for (int y = top; y < bottom; y++)
            {
                for (int x = left; x < right; x++)
                {
                    // Get the color of both pixels at this point
                    Color colorA = this.ColorMatrix[y - rectangleA.Top, x - rectangleA.Left];
                    Color colorB = go.ColorMatrix[y - rectangleB.Top, x - rectangleB.Left];

                    // If both pixels are not completely transparent,
                    if (colorA.A != 0 && colorB.A != 0)
                    {
                        // then an intersection has been found
                        position = new Vector(x, y);
                        return true;
                    }
                }
            }

            // No intersection found
            return false;
        }

        internal void CollisionDetection()
        {
            this.TouchObjList = new List<GraphicObj>();
            switch (this.CollisionDetectionLevel)
            {
                case CollisionDetectionLevels.None:
                    break;
                case CollisionDetectionLevels.PerPixelCollision:
                    this.PerPixelCollisionDetection();
                    break;
                case CollisionDetectionLevels.RectangleCollision:
                    this.RectangleCollisionDetection();
                    break;
                case CollisionDetectionLevels.TransformedCollision:
                    this.TransformedCollisionDetection();
                    break;
            }
        }

        internal void TransformedCollisionDetection()
        {
            Rectangle myRectangle = new Rectangle(0, 0, this.FrameSize.X, this.FrameSize.Y);
            myRectangle = CalculateBoundingRectangle(myRectangle, this.TransformMatrix);
            foreach (GraphicObj item in CollisionObjList)
            {
                if (item == this) { continue; }
                Rectangle otherRectangle;
                Vector position = new Vector(0, 0);

                switch (item.CollisionDetectionLevel)
                {
                    case CollisionDetectionLevels.None:
                        break;
                    case CollisionDetectionLevels.PerPixelCollision:
                        otherRectangle = item.Rectangle;
                        if (myRectangle.Intersects(otherRectangle))
                        {
                            if (this.TransformIntersectPixels(item, ref position))
                            {
                                //碰撞事件
                                this.RaiseCollisionEvent(position, item);
                            }
                        }
                        break;
                    case CollisionDetectionLevels.RectangleCollision:
                        otherRectangle = item.Rectangle;
                        if (myRectangle.Intersects(otherRectangle))
                        {
                            if (this.TransformIntersectPixels(item, ref position))
                            {
                                //碰撞事件
                                this.RaiseCollisionEvent(position, item);
                            }
                        }
                        break;
                    case CollisionDetectionLevels.TransformedCollision:
                        otherRectangle = new Rectangle(0, 0, item.FrameSize.X, item.FrameSize.Y);
                        if (myRectangle.Intersects(CalculateBoundingRectangle(otherRectangle, item.TransformMatrix)))
                        {
                            if (this.TransformIntersectPixels(item, ref position))
                            {
                                //碰撞事件
                                this.RaiseCollisionEvent(position, item);
                            }
                        }
                        break;
                }
            }
        }

        internal void PerPixelCollisionDetection()
        {
            foreach (GraphicObj item in CollisionObjList)
            {
                if (item == this) { continue; }
                Vector position = new Vector(0, 0);

                switch (item.CollisionDetectionLevel)
                {
                    case CollisionDetectionLevels.None:
                        break;
                    case CollisionDetectionLevels.PerPixelCollision:
                        if (this.IntersectPixels(item, ref position))
                        {
                            //碰撞事件
                            this.RaiseCollisionEvent(position, item);
                        }
                        break;
                    case CollisionDetectionLevels.RectangleCollision:
                        if (this.IntersectPixels(item, ref position))
                        {
                            //碰撞事件
                            this.RaiseCollisionEvent(position, item);
                        }
                        break;
                    case CollisionDetectionLevels.TransformedCollision:
                        if (this.IntersectPixels(item, ref position))
                        {
                            //碰撞事件
                            this.RaiseCollisionEvent(position, item);
                        }
                        break;
                }
            }
        }

        internal void RectangleCollisionDetection()
        {
            Rectangle myRectangle = this.Rectangle;
            foreach (GraphicObj item in CollisionObjList)
            {
                if (item == this) { continue; }
                if (item.CollisionDetectionLevel == CollisionDetectionLevels.None) { continue; }
                Rectangle otherRectangle = item.Rectangle;
                if (myRectangle.Intersects(otherRectangle))
                {
                    int top = System.Math.Max(myRectangle.Top, otherRectangle.Top);
                    int bottom = System.Math.Min(myRectangle.Bottom, otherRectangle.Bottom);
                    int left = System.Math.Max(myRectangle.Left, otherRectangle.Left);
                    int right = System.Math.Min(myRectangle.Right, otherRectangle.Right);
                    Vector position = new Vector((top + bottom) / 2.0f, (left + right) / 2.0f);
                    //碰撞事件
                    this.RaiseCollisionEvent(position, item);
                }
            }
        }

        internal static Rectangle CalculateBoundingRectangle(Rectangle rectangle,
                                                           Matrix transform)
        {
            // Get all four corners in local space
            Vector2 leftTop = new Vector2(rectangle.Left, rectangle.Top);
            Vector2 rightTop = new Vector2(rectangle.Right, rectangle.Top);
            Vector2 leftBottom = new Vector2(rectangle.Left, rectangle.Bottom);
            Vector2 rightBottom = new Vector2(rectangle.Right, rectangle.Bottom);

            // Transform all four corners into work space
            Vector2.Transform(ref leftTop, ref transform, out leftTop);
            Vector2.Transform(ref rightTop, ref transform, out rightTop);
            Vector2.Transform(ref leftBottom, ref transform, out leftBottom);
            Vector2.Transform(ref rightBottom, ref transform, out rightBottom);

            // Find the minimum and maximum extents of the rectangle in world space
            Vector2 min = Vector2.Min(Vector2.Min(leftTop, rightTop),
                                      Vector2.Min(leftBottom, rightBottom));
            Vector2 max = Vector2.Max(Vector2.Max(leftTop, rightTop),
                                      Vector2.Max(leftBottom, rightBottom));

            // Return that as a rectangle
            return new Rectangle((int)min.X, (int)min.Y,
                                 (int)(max.X - min.X), (int)(max.Y - min.Y));
        }
        internal void MouseButtonDownDetection()
        {
            if (this.MouseButtonDownDetectionLevel == MouseButtonDownDetectionLevels.None)
            {
                return;
            }
            else
            {
                this.LastMouseState = this.CurrentMouseState;
                this.CurrentMouseState = Mouse.GetState();
                //左键
                if ((CurrentMouseState.LeftButton == ButtonState.Pressed) && (LastMouseState.LeftButton == ButtonState.Released))
                {
                    Rectangle myRectangle = this.Rectangle;
                    if (myRectangle.Intersects(new Rectangle(CurrentMouseState.X, CurrentMouseState.Y, 1, 1)))
                    {
                        if (this.MouseButtonDownDetectionLevel == MouseButtonDownDetectionLevels.RectangleCollision)
                        {
                            //鼠标左键按下事件
                            MouseButtonDownInfo info = new MouseButtonDownInfo(this, new MouseButtonDownEventArgs(new Vector(CurrentMouseState.X, CurrentMouseState.Y)));
                            GraphicObj.AllMouseLeftButtonDown.Add(info);
                        }
                        else if (this.MouseButtonDownDetectionLevel == MouseButtonDownDetectionLevels.PerPixelCollision)
                        {
                            int x = CurrentMouseState.X - this.Rectangle.X;
                            int y = CurrentMouseState.Y - this.Rectangle.Y;
                            if (this.ColorMatrix[y, x].A != 0)
                            {
                                //鼠标左键按下事件
                                MouseButtonDownInfo info = new MouseButtonDownInfo(this, new MouseButtonDownEventArgs(new Vector(CurrentMouseState.X, CurrentMouseState.Y)));
                                GraphicObj.AllMouseLeftButtonDown.Add(info);
                            }
                        }
                    }
                }
                //右键
                if ((CurrentMouseState.RightButton == ButtonState.Pressed) && (LastMouseState.RightButton == ButtonState.Released))
                {
                    Rectangle myRectangle = this.Rectangle;
                    if (myRectangle.Intersects(new Rectangle(CurrentMouseState.X, CurrentMouseState.Y, 1, 1)))
                    {
                        if (this.MouseButtonDownDetectionLevel == MouseButtonDownDetectionLevels.RectangleCollision)
                        {
                            //鼠标右键按下事件
                            MouseButtonDownInfo info = new MouseButtonDownInfo(this, new MouseButtonDownEventArgs(new Vector(CurrentMouseState.X, CurrentMouseState.Y)));
                            GraphicObj.AllMouseRightButtonDown.Add(info);
                        }
                        else if (this.MouseButtonDownDetectionLevel == MouseButtonDownDetectionLevels.PerPixelCollision)
                        {
                            int x = CurrentMouseState.X - this.Rectangle.X;
                            int y = CurrentMouseState.Y - this.Rectangle.Y;
                            if (this.ColorMatrix[y, x].A != 0)
                            {
                                //鼠标右键按下事件
                                MouseButtonDownInfo info = new MouseButtonDownInfo(this, new MouseButtonDownEventArgs(new Vector(CurrentMouseState.X, CurrentMouseState.Y)));
                                GraphicObj.AllMouseRightButtonDown.Add(info);
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 设置当前帧所在行
        /// </summary>
        /// <param name="y">当前帧所在行</param>
        public void SetCurrentFrameY(int y)
        {
            this._CurrentFrame.Y = y;
            this.ColorMatrixUpdate();
        }
        /// <summary>
        /// 设置当前帧所在列
        /// </summary>
        /// <param name="x">当前帧所在列</param>
        public void SetCurrentFrameX(int x)
        {
            this._CurrentFrame.X = x;
            this.ColorMatrixUpdate();
        }
        /// <summary>
        /// 根据设置的中心坐标返回对应的左上角坐标
        /// </summary>
        /// <param name="centre">中心坐标</param>
        /// <returns>对应的左上角坐标</returns>
        public Vector GetPositionFromCentre(Vector centre)
        {
            return new Vector(centre.X - Size.X / 2.0f + Origin.X, centre.Y - Size.Y / 2.0f + Origin.Y);
        }

        /// <summary>
        /// 渲染当前帧，置于Draw()下
        /// </summary>
        /// <param name="spriteBatch">SpriteBatch实例</param>
        public override void Draw()
        {
            SpriteBatch spriteBatch = Engine.SpriteBatch;
            spriteBatch.Draw(
                this.Resource,
                new Vector2(this.Position.X, this.Position.Y),
                new Rectangle(CurrentFrame.X * FrameSize.X, CurrentFrame.Y * FrameSize.Y, FrameSize.X, FrameSize.Y),
                this.Color,
                this.Rotation,
                this.Origin,
                this.Scale,
                this.Effects,
                this.LayerDepth
                );
        }
        /// <summary>
        /// 渲染当前帧，置于Draw()下
        /// </summary>
        /// <param name="spriteBatch">SpriteBatch实例</param>
        /// <param name="layerDepth">层深，层1表示这个层首先绘制，层0表示最后绘制，在所有其它层之上</param>
        public void Draw(SpriteBatch spriteBatch, float layerDepth)
        {
            spriteBatch.Draw(
                this.Resource,
                new Vector2(this.Position.X, this.Position.Y),
                new Rectangle(CurrentFrame.X * FrameSize.X, CurrentFrame.Y * FrameSize.Y, FrameSize.X, FrameSize.Y),
                this.Color,
                this.Rotation,
                this.Origin,
                this.Scale,
                this.Effects,
                layerDepth
                );
        }
        /// <summary>
        /// 渲染当前帧，置于Draw()下
        /// </summary>
        /// <param name="spriteBatch">SpriteBatch实例</param>
        /// <param name="color">渲染色彩</param>
        /// <param name="rotation">旋转角度</param>
        /// <param name="origin">旋转原点</param>
        /// <param name="scale">缩放</param>
        /// <param name="effects">翻转等效果</param>
        /// <param name="layerDepth">层深，层1表示这个层首先绘制，层0表示最后绘制，在所有其它层之上</param>
        public void Draw(SpriteBatch spriteBatch, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effects, float layerDepth)
        {
            spriteBatch.Draw(
                this.Resource,
                new Vector2(this.Position.X, this.Position.Y),
                new Rectangle(CurrentFrame.X * FrameSize.X, CurrentFrame.Y * FrameSize.Y, FrameSize.X, FrameSize.Y),
                color,
                rotation,
                origin,
                scale,
                effects,
                layerDepth
                );
        }

        /// <summary>
        /// 触发碰撞事件
        /// </summary>
        /// <param name="position">碰撞事件位置</param>
        /// <param name="otherObj">碰撞事件另一方</param>
        private void RaiseCollisionEvent(Vector position, GraphicObj otherObj)
        {
            this.TouchObjList.Add(otherObj);

            //////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////
            //////////////////2012.04.02修改以支持物理引擎///////////////////////////////
            ////////////////该部分主要功能为测算物体所在平面角度///////////////////////////
            //////////////////////////////////////////////////////////////////////////
            Rectangle rect = GetSmallRectangle(position, otherObj);
            Vector firstPoint = Vector.Zero;
            Vector secondPoint = Vector.Zero;
            int left = rect.Left;
            int right = rect.Right;
            int top = rect.Top;
            int bottom = rect.Bottom;
            //测算左侧关键点角度
            for (int i = top; i <= bottom; ++i)
            {
                //从顶向下寻找第一列
                if (otherObj.ColorMatrix[i, left].A != 0)
                {
                    if (i != top)
                    {
                        firstPoint = new Vector(left, i);
                        break;
                    }
                    else//若第一行发现关键点，则依次遍历第一行
                    {
                        //j < right 注意！！！，并非<=
                        for (int j = left; j < right; ++j)
                        {
                            if (otherObj.ColorMatrix[top, j].A != 0 && otherObj.ColorMatrix[top, j + 1].A == 0)
                            {
                                firstPoint = new Vector(j, top);
                            }
                            else
                            {
                                if (j == right - 1)
                                {
                                    firstPoint = new Vector(right, top);
                                }
                            }
                        }
                    }
                }
            }

            //测算右侧关键点角度
            for (int i = top; i <= bottom; ++i)
            {
                if (otherObj.ColorMatrix[i, right].A != 0)
                {
                    if (i != top)
                    {
                        secondPoint = new Vector(right, i);
                        break;
                    }
                    else
                    {
                        //j > left 注意！！！，并非>=
                        for (int j = right; j > left; --j)
                        {
                            if (otherObj.ColorMatrix[top, j].A != 0 && otherObj.ColorMatrix[top, j - 1].A == 0)
                            {
                                secondPoint = new Vector(j, top);
                            }
                            else
                            {
                                if (j == left + 1)
                                {
                                    secondPoint = new Vector(left, top);
                                }
                            }
                        }
                    }
                }
            }

            double sx = (double)secondPoint.X;
            double sy = (double)secondPoint.Y;
            double fx = (double)firstPoint.X;
            double fy = (double)firstPoint.Y;

            this.Physics.Theta = (float)Math.Atan((sy - fy) / ((sx - fx) == 0d ? 0.001d : (sx - fx)));

            CollisionEventArgs e = new CollisionEventArgs(position, otherObj);
            this.OnCollisionEvent(e);
        }

        private static Rectangle GetSmallRectangle(Vector position, GraphicObj otherObj)
        {
            int startX = (int)position.X >= 10 ? (int)position.X - 10 : 0;
            int startY = (int)position.Y >= 10 ? (int)position.Y - 10 : 0;
            //////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////
            //////////////////2012.04.02修改以支持物理引擎///////////////////////////////
            //////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////
            int endX = (int)position.X <= 789 ? (int)position.X + 10 : 799;
            //////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////
            //////////////////2012.04.02修改以支持物理引擎///////////////////////////////
            //////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////
            int endY = (int)position.Y <= 469 ? (int)position.Y + 10 : 479;
            return new Rectangle(startX, startY, endX - startX, endY - startY);
        }

        /// <summary>
        /// 触发事件的方法，可重载
        /// </summary>
        /// <param name="e">碰撞事件参数</param>
        private void OnCollisionEvent(CollisionEventArgs e)
        {
            _Collision(this, e);
        }

        private static void OnCollision(object sender, CollisionEventArgs e)
        {
        }

        private static void OnMouseButtonDown(object sender, MouseButtonDownEventArgs e)
        {
        }

        private static void OnLastFrame(object sender, LastFrameEventArgs e)
        {
        }

        /// <summary>
        /// 碰撞事件
        /// </summary>
        /// <param name="sender">事件发送者</param>
        /// <param name="e">事件参数处理器</param>
        public delegate void CollisionEventHandler(object sender, CollisionEventArgs e);

        /// <summary>
        /// 鼠标左键按下事件
        /// </summary>
        /// <param name="sender">事件发送者</param>
        /// <param name="e">事件参数处理器</param>
        public delegate void MouseLeftButtonDownEventHandler(object sender, MouseButtonDownEventArgs e);

        /// <summary>
        /// 鼠标右键按下事件
        /// </summary>
        /// <param name="sender">事件发送者</param>
        /// <param name="e">事件参数处理器</param>
        public delegate void MouseRightButtonDownEventHandler(object sender, MouseButtonDownEventArgs e);

        /// <summary>
        /// 最后帧事件
        /// </summary>
        /// <param name="sender">事件发送者</param>
        /// <param name="e">事件参数处理器</param>
        public delegate void LastFrameEventHandler(object sender, LastFrameEventArgs e);

        private void RaiseMouseLeftButtonDownEvent(Vector position)
        {
            MouseButtonDownEventArgs e = new MouseButtonDownEventArgs(position);
            this.OnMouseLeftButtonDownEvent(e);
        }

        /// <summary>
        /// 鼠标左键事件发生时
        /// </summary>
        /// <param name="e">鼠标左键事件参数</param>
        private void OnMouseLeftButtonDownEvent(MouseButtonDownEventArgs e)
        {
            if (true)
            {
                _MouseLeftButtonDown(this, e);
            }
        }

        private void RaiseMouseRightButtonDownEvent(Vector position)
        {
            MouseButtonDownEventArgs e = new MouseButtonDownEventArgs(position);
            this.OnMouseRightButtonDownEvent(e);
        }

        /// <summary>
        /// 鼠标右键事件发生时
        /// </summary>
        /// <param name="e">鼠标右键事件参数</param>
        private void OnMouseRightButtonDownEvent(MouseButtonDownEventArgs e)
        {
            if (true)
            {
                _MouseRightButtonDown(this, e);
            }
        }

        private void RaiseLastFrameEvent(int frameCount, int circleCount)
        {
            LastFrameEventArgs e = new LastFrameEventArgs(frameCount, circleCount);
            this.OnLastFrameEvent(e);
        }

        private void OnLastFrameEvent(LastFrameEventArgs e)
        {
            if (true)
            {
                _LastFrame(this, e);
            }
        }
        #endregion 原GO属性

    }
}
